package com.imooc.service.impl;

import com.imooc.exception.SellException;
import com.imooc.service.RedisLock;
import com.imooc.service.SeckillService;
import com.imooc.utils.KeyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 模块描述: <br>
 * ()
 *
 * @Author:Mr. xyb
 * @Date: 2018/5/25 15:01
 * @since: 1.8.0
 * @version: 1.0.0
 */
@Service
public class SeckillServiceImpl implements SeckillService {

    private static final long TIMEOUT = 10 * 1000;

    @Autowired
    private RedisLock redisLock;


    static Map<String, Integer> products;
    static Map<String, Integer> stocks;
    static Map<String, String> orders;

    static {
        products = new HashMap<>();
        stocks = new HashMap<>();
        orders = new HashMap<>();
        products.put("12345", 100000);
        stocks.put("12345", 100000);
    }

    private String queryMap(String productId) {
        return "国庆活动，皮蛋粥特价，限量份"
                + products.get(productId)
                + "还剩：" + stocks.get(productId) + "份"
                + "该商品成功下单用户数目："
                + orders.size() + " 人";
    }

    @Override
    public String querySeckillProductInfo(String productId) {
        return this.queryMap(productId);
    }

    /**
     * 存在多线程，使用synchronized可以解决，可是效率低
     * 推荐使用redis分布式锁
     *
     * @param productId 商品id
     */
    @Override
    public void orderProductMockDiffUser(String productId) {

        // 定义一个超时变量
        long time = System.currentTimeMillis() + TIMEOUT;
        // 加锁
        if (!redisLock.lock(productId, String.valueOf(time))) {
            throw new SellException(101, "哎呦喂, 人也太多了，换个姿势再试试");
        }
        // 1.查询该商品库存，为0则活动结束
        int stockNum = stocks.get(productId);
        if (stockNum == 0) {
            throw new SellException(100, "活动结束");
        } else {
            // 2.下单
            orders.put(KeyUtils.getUniqueKey(), productId);
            // 3.减库存
            stockNum = stockNum - 1;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stocks.put(productId, stockNum);
        }
        // 解锁
        redisLock.unlock(productId, String.valueOf(time));
    }
}
